package pro.shuangxi.source;

import cn.hutool.core.date.format.FastDateFormat;
import cn.hutool.core.text.NamingCase;
import cn.hutool.db.ds.simple.SimpleDataSource;
import pro.shuangxi.utils.StringUtils;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @author mengshx
 **/
public class MysqlTableMapSource implements MapSource{
    String  url;
    String  username ;
    String  password;
    String  tableName;
    String  perfix="";
    String  suffix="";

    DataSource dataSource;
    Map<String, Object> map = new HashMap<>();
    public MysqlTableMapSource(DataSource dataSource, String tableName) {
        this.dataSource = dataSource;
        this.tableName = tableName;
    }

    /**
     *
     * @param url
     * @param username
     * @param password
     * @param tableName
     */
    public MysqlTableMapSource(String url, String username, String password, String tableName) {
        this.url = url;
        this.username = username;
        this.password = password;
        this.tableName = tableName;
        SimpleDataSource simpleDataSource = new SimpleDataSource(url,username,password);
        simpleDataSource.setDriver("com.mysql.jdbc.Driver");
        dataSource = simpleDataSource;
    }

    public Map<String,Object> getMap(){
        try {
            Connection connection = dataSource.getConnection();
            String sql = "SELECT\n" +
                    "\tcolumn_name,\n" +
                    "\t( CASE WHEN ( is_nullable = 'no' && column_key != 'PRI' ) THEN '1' ELSE NULL END ) AS is_required,\n" +
                    "\t( CASE WHEN column_key = 'PRI' THEN '1' ELSE '0' END ) AS is_pk,\n" +
                    "\tordinal_position AS sort,\n" +
                    "\tcolumn_comment,\n" +
                    "\t( CASE WHEN extra = 'auto_increment' THEN '1' ELSE '0' END ) AS is_increment,\n" +
                    "\tcolumn_type, \n" +
                    "\tdata_type \n" +
                    "FROM\n" +
                    "\tinformation_schema.COLUMNS \n" +
                    "WHERE\n" +
                    "\ttable_schema = ( SELECT DATABASE ( ) ) \n" +
                    "\tAND table_name = (?)\n" +
                    "\t\t\n" +
                    "ORDER BY\n" +
                    "\tordinal_position";
            PreparedStatement statement = connection.prepareStatement(sql);
            statement.setString(1, tableName);
            ResultSet resultSet = statement.executeQuery();


            ArrayList<HashMap<String, Object>> columns = new ArrayList<>();
            while (resultSet.next()) {
                HashMap<String, Object> column = new HashMap<>();
                column.put("column_name",resultSet.getString("column_name"));
                column.put("COLUMN_NAME",resultSet.getString("column_name").toUpperCase());
                column.put("ColumnName", NamingCase.toPascalCase(resultSet.getString("column_name")));
                column.put("columnName",NamingCase.toCamelCase(resultSet.getString("column_name")));
                column.put("column-name", NamingCase.toKebabCase(NamingCase.toPascalCase(resultSet.getString("column_name"))));
                column.put("COLUMNNAME", resultSet.getString("column_name").toUpperCase().replace("_", ""));
                column.put("isRequired",resultSet.getString("is_required"));
                String is_pk = resultSet.getString("is_pk");
                column.put("isPk",is_pk);
                if("1".equals(is_pk)){
                    String column_name = resultSet.getString("column_name");
                    map.put("key_name", column_name);
                    map.put("keyName", NamingCase.toCamelCase(column_name));
                    map.put("KeyName", NamingCase.toPascalCase(column_name));
                }
                column.put("sort",resultSet.getString("sort"));
                column.put("columnComment",resultSet.getString("column_comment"));
                column.put("isIncrement",resultSet.getString("is_increment"));
                column.put("columnType",resultSet.getString("column_type"));
                column.put("dataType",resultSet.getString("data_type"));
                switch ((String)column.get("dataType")) {
                    case "bigint":{
                        column.put("javaType", "Long");
                        column.put("jsType", "number");
                        break;
                    }
                    case "tinyint":
                    case "smallint":
                    case "int":{
                        //主键建议Long
                        if (column.get("isPk").equals("1")) {
                            column.put("javaType", "Long");
                            column.put("jsType", "number");
                        }else {
                            column.put("javaType", "Integer");
                            column.put("jsType", "number");
                        }

                        break;
                    }
                    case "timestamp":
                    case "datetime":{
                        column.put("javaType", "Date");
                        column.put("jsType", "string");
                        break;
                    }
                    case "varchar":{
                        column.put("javaType", "String");
                        column.put("jsType", "string");
                        break;
                    }
                    default:{
                        column.put("javaType", "String");
                        column.put("jsType", "string");
                    }
                }
                columns.add(column);
            }
            PreparedStatement tableStatement = connection.prepareStatement("SELECT\n" +
                    "\tTABLE_COMMENT\n" +
                    "FROM\n" +
                    "\tinformation_schema.TABLES \n" +
                    "WHERE\n" +
                    "\ttable_schema = ( SELECT DATABASE ( ) ) \n" +
                    "\tAND table_name = (?)");
            tableStatement.setString(1, tableName);
            ResultSet tableResultSet = tableStatement.executeQuery();
            if (tableResultSet.next()) {
                String string = tableResultSet.getString(1);
                map.put("tableComment", string);
            }
            map.put("columns", columns);
            String subTableName=tableName;
            if (tableName.startsWith(perfix)) {
                subTableName = tableName.replaceFirst(perfix, "");
            }
            if (subTableName.endsWith(suffix)) {
                subTableName = subTableName.replace(suffix, "");
            }
            map.put("table_name", tableName);
            map.put("table-name", NamingCase.toKebabCase(NamingCase.toPascalCase(subTableName)));
            map.put("tableName", StringUtils.toCamelCase(subTableName));
            map.put("TableName", StringUtils.convertToCamelCase(subTableName));
            map.put("TABLENAME", subTableName.toUpperCase());
            map.put("date", FastDateFormat.getInstance().format(new Date()));

        } catch (SQLException e) {
            e.printStackTrace();
        }
        return map;
    }
    public void put(String key, Object value) {
        if (map.get(key) != null) {
            System.out.println("覆盖了key:" + key);
        }
        map.put(key, value);
    }
    public void setPackage(String packagePath) {
        map.put("package", packagePath);
    }
    public void setPerfix(String perfix) {
        this.perfix = perfix;
    }
    public void setSuffix(String suffix) {
        this.suffix = suffix;
    }
    public void setAuthor(String author) {
        map.put("author", author);
    }
}
